package com.pro.common.api.depencies;

import com.pro.common.api.R;
import com.pro.common.api.exception.BusinessNoTranslateException;
import com.pro.common.api.model.ILoginInfo;
import com.pro.framework.api.util.JSONUtils;
import com.pro.framework.api.util.StrUtils;
import feign.Logger;
import feign.Request;
import feign.RequestInterceptor;
import feign.Response;
import feign.codec.ErrorDecoder;
import jakarta.servlet.http.HttpServletRequest;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StreamUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

@Configuration
@Slf4j
public class FeignConfig {

    public static final String ACCEPT_LANGUAGE = "Accept-Language";
    public static final String X_FEIGN_REQUEST = "X-Feign-Request";

    @Bean
    public RequestInterceptor feignRequestInterceptor() {
        return template -> {
            // 标识当前请求为 feign 请求
            template.header(X_FEIGN_REQUEST, "true");

            // 获取当前请求（来自 SpringMVC 上下文）
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            if (requestAttributes instanceof ServletRequestAttributes servletRequestAttributes) {
                HttpServletRequest request = servletRequestAttributes.getRequest();

                // 传递登录信息 Header
                String userInfoHeader = request.getHeader(ILoginInfo.HEADER_KEY_MAIN);
                String roleHeader = request.getHeader(ILoginInfo.HEADER_KEY_ROLE);

                if (userInfoHeader != null) {
                    template.header(ILoginInfo.HEADER_KEY_MAIN, userInfoHeader);
                }
                if (roleHeader != null) {
                    template.header(ILoginInfo.HEADER_KEY_ROLE, roleHeader);
                }

                // ✅ 传递语言头 Accept-Language
                String language = request.getHeader(ACCEPT_LANGUAGE);
                if (language != null) {
                    template.header(ACCEPT_LANGUAGE, language);
                }
            }
        };
    }


    @SneakyThrows
    public Exception decode(String methodKey, Response response) {
        Response.Body body = response.body();
        String url = response.request().url();
        String msg = "";
        Integer code = null;
        if (body == null) {
            msg = "服务异常_请稍后重试";
        } else {
            String s = null;
            try {
                s = StreamUtils.copyToString(body.asInputStream(), StandardCharsets.UTF_8);
            } catch (IOException ex) {
                log.error("Error reading response body", ex);
            }
            if (s != null) {
                R r = JSONUtils.fromString(s, R.class);
                msg = r.getMsg();
                code = r.getCode();
            }
        }
        msg = null == msg ? "" : msg;
        log.error("BusinessNoTranslateException {} {}", url, msg);
        BusinessNoTranslateException e = new BusinessNoTranslateException(msg);
        e.setMsg(msg);
        e.setCode(code);
        return e;
    }


    @Bean
    public Logger feignLogger() {
        return new Logger() {
            @Override
            protected void log(String configKey, String format, Object... args) {
                // 只输出简短格式
                System.out.printf("%s - %s%n", configKey, String.format(format, args));
            }

            @Override
            protected void logRequest(String configKey, Level logLevel, Request request) {
                System.out.printf("Feign Request: %s %s%n", request.httpMethod(), request.url());
            }

            @Override
            protected Response logAndRebufferResponse(String configKey, Level logLevel, Response response, long elapsedTime) {
                System.out.printf("Feign Response: %s - %d (%d ms)%n", response.request().url(), response.status(),
                        elapsedTime);
                return response;
            }
        };
    }
}
